package lumis.service.wsrp.consumer.producermanager;

import java.io.Serializable;
import java.util.Date;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import lumis.service.wsrp.common.WSRPUtils;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;

import com.sun.portal.wsrp.common.stubs.v2.RegistrationContext;
import com.sun.portal.wsrp.common.stubs.v2.RegistrationState;
import com.sun.portal.wsrp.consumer.producermanager.ProducerEntity;

/**
 * Registration entity.
 *
 * @version $Revision: 13092 $ $Date: 2011-05-28 18:19:06 -0300 (Sat, 28 May 2011) $
 * @since 6.0.0
 */
@Entity
@Table(name = "lum_WsrpCRegistration")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@SuppressWarnings("serial")
public class Registration implements Serializable
{
	@Id	
	@Column(name = "registrationHandle")
	private String registrationHandle;
	
	@Column(name = "registrationState")
	private byte[] registrationState;
	
	private transient Date scheduledDestruction;
	
	@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="registration")
	@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
	private Set<ClonedPortlet> clonedPortlets;
	
	@OneToOne
	@JoinColumn(name="producerEntityId")
	private ProducerEntityImpl producerEntity;

	Registration()
	{
	}
	
	Registration(RegistrationContext registrationContext, ProducerEntity producerEntity)
	{
		this.registrationHandle = registrationContext.getRegistrationHandle();
		this.registrationState = registrationContext.getRegistrationState();
		
		if (registrationContext.getScheduledDestruction() != null)
		{
			this.scheduledDestruction = registrationContext.getScheduledDestruction().getTerminationTime().toGregorianCalendar().getTime();
		}
		this.producerEntity = (ProducerEntityImpl) producerEntity;
	}
	
	
	public Set<ClonedPortlet> getClonedPortlets()
	{
		return this.clonedPortlets;
	}

	public void setClonedPortlets(Set<ClonedPortlet> clonedPortlets)
	{
		this.clonedPortlets = clonedPortlets;
	}
	
	public void addClonedPortlet(ClonedPortlet clonedPortlet)
	{
		clonedPortlet.setRegistration(this);
		this.clonedPortlets.add(clonedPortlet);
	}
	
	public Date getLifetime()
	{
		return this.scheduledDestruction;
	}
	
	void setLifetime(Date lifetime)
	{
		this.scheduledDestruction = lifetime;
	}
	
	public RegistrationContext getRegistrationContext()
	{
		RegistrationContext registrationContext = new RegistrationContext();
		registrationContext.setRegistrationHandle(this.registrationHandle);
		registrationContext.setRegistrationState(this.registrationState);
		registrationContext.setScheduledDestruction(WSRPUtils.lifetimeTerminationTimeFromDate(this.scheduledDestruction));
		
		return registrationContext;
	}
	
	void setRegistrationContext(RegistrationContext registrationContext)
	{
		if (registrationContext != null)
		{
			if (registrationContext.getRegistrationHandle().equals(this.registrationHandle))
			{
				this.registrationState = registrationContext.getRegistrationState();
				this.scheduledDestruction = WSRPUtils.lifetimeTerminationTimeToDate(registrationContext.getScheduledDestruction());
			}
			else
			{
				throw new IllegalArgumentException("The registration handle passed is different from the current registration handle.");
			}
		}
		else
		{
			throw new IllegalArgumentException("The RegistrationContext can not be null.");
		}
	}
	
	public String getRegistrationHandle()
	{
		return this.registrationHandle;
	}
	
	public RegistrationState getRegistrationState()
	{
		RegistrationState registrationState = new RegistrationState();
		registrationState.setRegistrationState(this.registrationState);
		registrationState.setScheduledDestruction(WSRPUtils.lifetimeTerminationTimeFromDate(this.scheduledDestruction));
	
		return registrationState;
	}
	
	public ProducerEntity getProducerEntity()
	{
		return producerEntity;
	}

	public void setProducerEntity(ProducerEntity producerEntity)
	{
		this.producerEntity = (ProducerEntityImpl) producerEntity;
	}
}